import 'package:math_keyboard/src/foundation/node.dart';
import 'package:math_keyboard/src/foundation/extended_nodes.dart';

/// Helper class for enhanced navigation in complex mathematical structures.
class NavigationEnhancements {
  
  /// Navigates within a subscript/superscript structure.
  // static NavigationState navigateSubscriptSuperscript(
  //   TeXSubscriptSuperscript node,
  //   TeXNode currentNode,
  //   bool goingForward,
  //   Function(TeXNode) setCurrentNode,
  // ) {
  //   final currentArgIndex = node.argNodes.indexOf(currentNode);
  //
  //   if (goingForward) {
  //     // Moving forward through subscript -> superscript
  //     if (currentArgIndex < node.argNodes.length - 1) {
  //       // Move to next argument (subscript to superscript)
  //       currentNode.removeCursor();
  //       final nextNode = node.argNodes[currentArgIndex + 1];
  //       nextNode.courserPosition = 0;
  //       nextNode.setCursor();
  //       setCurrentNode(nextNode);
  //       return NavigationState.success;
  //     } else {
  //       // At the end, exit the structure
  //       return NavigationState.end;
  //     }
  //   } else {
  //     // Moving backward through superscript -> subscript
  //     if (currentArgIndex > 0) {
  //       // Move to previous argument (superscript to subscript)
  //       currentNode.removeCursor();
  //       final prevNode = node.argNodes[currentArgIndex - 1];
  //       prevNode.courserPosition = prevNode.children.length;
  //       prevNode.setCursor();
  //       setCurrentNode(prevNode);
  //       return NavigationState.success;
  //     } else {
  //       // At the beginning, exit the structure
  //       return NavigationState.end;
  //     }
  //   }
  // }

  /// Navigates within a matrix structure.
  static NavigationState navigateMatrix(
    TeXMatrix matrix,
    TeXNode currentNode,
    bool goingForward,
    Function(TeXNode) setCurrentNode,
  ) {
    final currentCellIndex = matrix.argNodes.indexOf(currentNode);
    final currentRow = currentCellIndex ~/ matrix.columns;
    final currentCol = currentCellIndex % matrix.columns;
    
    if (goingForward) {
      // Move to next cell (left to right, top to bottom)
      if (currentCol < matrix.columns - 1) {
        // Move to next column in same row
        _moveToMatrixCell(matrix, currentRow, currentCol + 1, currentNode, setCurrentNode);
        return NavigationState.success;
      } else if (currentRow < matrix.rows - 1) {
        // Move to first column of next row
        _moveToMatrixCell(matrix, currentRow + 1, 0, currentNode, setCurrentNode);
        return NavigationState.success;
      } else {
        // At the last cell, exit the matrix
        return NavigationState.end;
      }
    } else {
      // Move to previous cell (right to left, bottom to top)
      if (currentCol > 0) {
        // Move to previous column in same row
        _moveToMatrixCell(matrix, currentRow, currentCol - 1, currentNode, setCurrentNode);
        return NavigationState.success;
      } else if (currentRow > 0) {
        // Move to last column of previous row
        _moveToMatrixCell(matrix, currentRow - 1, matrix.columns - 1, currentNode, setCurrentNode);
        return NavigationState.success;
      } else {
        // At the first cell, exit the matrix
        return NavigationState.end;
      }
    }
  }

  /// Navigates within a limit expression (integral, sum, etc.).
  static NavigationState navigateLimitExpression(
    TeXLimitExpression expr,
    TeXNode currentNode,
    bool goingForward,
    Function(TeXNode) setCurrentNode,
  ) {
    final currentArgIndex = expr.argNodes.indexOf(currentNode);
    
    if (goingForward) {
      // Move forward through: lower limit -> upper limit -> body (if exists)
      if (currentArgIndex < expr.argNodes.length - 1) {
        // Move to next argument
        currentNode.removeCursor();
        final nextNode = expr.argNodes[currentArgIndex + 1];
        nextNode.courserPosition = 0;
        nextNode.setCursor();
        setCurrentNode(nextNode);
        return NavigationState.success;
      } else {
        // At the end, exit the structure
        return NavigationState.end;
      }
    } else {
      // Move backward through: body -> upper limit -> lower limit
      if (currentArgIndex > 0) {
        // Move to previous argument
        currentNode.removeCursor();
        final prevNode = expr.argNodes[currentArgIndex - 1];
        prevNode.courserPosition = prevNode.children.length;
        prevNode.setCursor();
        setCurrentNode(prevNode);
        return NavigationState.success;
      } else {
        // At the beginning, exit the structure
        return NavigationState.end;
      }
    }
  }

  // Private helper methods

  static void _moveToMatrixCell(
    TeXMatrix matrix, 
    int row, 
    int col, 
    TeXNode currentNode, 
    Function(TeXNode) setCurrentNode
  ) {
    currentNode.removeCursor();
    final targetCell = matrix.getCell(row, col);
    targetCell.courserPosition = 0;
    targetCell.setCursor();
    setCurrentNode(targetCell);
  }
}

/// Placeholder navigator for jumping between empty placeholders.
class PlaceholderNavigator {
  /// Finds all empty placeholders in the document.
  static List<EditableBox> findAllPlaceholders(TeXNode root) {
    final placeholders = <EditableBox>[];
    _findPlaceholdersRecursive(root, placeholders);
    return placeholders;
  }

  /// Jumps to the next empty placeholder.
  static TeXNode? jumpToNextPlaceholder(TeXNode root, TeXNode currentNode) {
    final placeholders = findAllPlaceholders(root);
    final emptyPlaceholders = placeholders.where((p) => p.isEmpty).toList();
    
    if (emptyPlaceholders.isEmpty) return null;
    
    // Find the next placeholder after the current cursor position
    // For now, just jump to the first empty placeholder
    final nextPlaceholder = emptyPlaceholders.first;
    currentNode.removeCursor();
    nextPlaceholder.content.courserPosition = 0;
    nextPlaceholder.content.setCursor();
    return nextPlaceholder.content;
  }

  /// Jumps to the previous empty placeholder.
  static TeXNode? jumpToPreviousPlaceholder(TeXNode root, TeXNode currentNode) {
    final placeholders = findAllPlaceholders(root);
    final emptyPlaceholders = placeholders.where((p) => p.isEmpty).toList();
    
    if (emptyPlaceholders.isEmpty) return null;
    
    // Find the previous placeholder before the current cursor position
    // For now, just jump to the last empty placeholder
    final prevPlaceholder = emptyPlaceholders.last;
    currentNode.removeCursor();
    prevPlaceholder.content.courserPosition = 0;
    prevPlaceholder.content.setCursor();
    return prevPlaceholder.content;
  }

  static void _findPlaceholdersRecursive(TeXNode node, List<EditableBox> placeholders) {
    for (final child in node.children) {
      if (child is EditableBox) {
        placeholders.add(child);
      } else if (child is TeXFunction) {
        for (final argNode in child.argNodes) {
          _findPlaceholdersRecursive(argNode, placeholders);
        }
      }
    }
  }
}